using System;
using System.Collections.Generic;

using SBPweb.Common.Authorization;
using SBPweb.Common.Caching;
using SBPweb.Common.Session;

using SBPweb.PROvibe.Resources.Warehouse.Theme;

using SBPweb.PROvibe.Business.Logic;

namespace SBPweb.PROvibe.Business.Warehouse
{
	public class ThemeFactory
	{

		#region Private static string constants

		private static string CACHEKEY_THEMES = "Warehouse.Themes";
		private static string CACHEKEY_THEMES_INDEX_ID = "Warehouse.Themes.Index.Id";
		private static string CACHEKEY_THEMES_INDEX_NAME = "Warehouse.Themes.Index.Name";

		private static string SESSIONKEY_THEMES = "_Repository.Themes";

		#endregion

		#region Private fields

		private static ThemeRepository mThemeRepository
		{
			get
			{
				ThemeRepository ret = SessionHandler.Get<ThemeRepository>(SESSIONKEY_THEMES);

				if (ret == null)
				{
					ret = new ThemeRepository(ConfigurationManager.ConnectionStrings.Warehouse);
					SessionHandler.Put<ThemeRepository>(SESSIONKEY_THEMES, ret);
				}

				return ret;
			}
		}

		#endregion

		#region Constructor logic

		private ThemeFactory()
		{
		}

		#endregion

		#region Repository handler methods

		#region Create

		public static Entities.Theme CreateTheme(string name)
		{
			Resources.Entities.Theme theme = new Resources.Entities.Theme();

			theme.Name = name;

			mThemeRepository.Add(theme);

			return ConvertResourcesEntity(theme);
		}

		#endregion

		#region Read

		public static List<Entities.Theme> ReadThemes()
		{
			bool isCached = ConfigurationManager.CacheExpirations.IsCachingUsed;

			if (isCached && CacheHandler.GetAccessLogClone().ContainsKey(CACHEKEY_THEMES))
			{
				return CacheHandler.Retrieve<List<Entities.Theme>>(CACHEKEY_THEMES);
			}

			List<Entities.Theme> themes = ConvertResourcesEntityList(mThemeRepository.GetThemes());

			if (isCached)
			{
				CacheHandler.Store<List<Entities.Theme>>(CACHEKEY_THEMES, themes, ConfigurationManager.CacheExpirations.Warehouse.Themes);

				Dictionary<int, Entities.Theme> indexId = new Dictionary<int, Entities.Theme>();
				Dictionary<string, Entities.Theme> indexName = new Dictionary<string, Entities.Theme>();

				foreach (Entities.Theme theme in themes)
				{
					indexId.Add(theme.Id, theme);
					indexName.Add(theme.Name, theme);
				}

				CacheHandler.Store<Dictionary<int, Entities.Theme>>(CACHEKEY_THEMES_INDEX_ID, indexId, ConfigurationManager.CacheExpirations.Warehouse.Themes);
				CacheHandler.Store<Dictionary<string, Entities.Theme>>(CACHEKEY_THEMES_INDEX_NAME, indexName, ConfigurationManager.CacheExpirations.Warehouse.Themes);
			}

			return themes;
		}

		public static Entities.Theme ReadThemeById(int themeId)
		{
			bool isCached = ConfigurationManager.CacheExpirations.IsCachingUsed;
			Dictionary<int, Entities.Theme> index = null;

			if (isCached && CacheHandler.GetAccessLogClone().ContainsKey(CACHEKEY_THEMES_INDEX_ID))
			{
				index = CacheHandler.Retrieve<Dictionary<int, Entities.Theme>>(CACHEKEY_THEMES_INDEX_ID);
				if (index.ContainsKey(themeId))
				{
					return index[themeId];
				}
			}

            Resources.Entities.Theme resource = mThemeRepository.GetThemeById(themeId);
            Entities.Theme theme = null;
            if (resource != null)
            {
                theme = ConvertResourcesEntity(resource);
            }

			if (index != null)
			{
				index.Add(themeId, theme);
			}

			return theme;
		}

		public static Entities.Theme ReadThemeByName(string themeName)
		{
			bool isCached = ConfigurationManager.CacheExpirations.IsCachingUsed;
			Dictionary<string, Entities.Theme> index = null;

			if (isCached && CacheHandler.GetAccessLogClone().ContainsKey(CACHEKEY_THEMES_INDEX_NAME))
			{
				index = CacheHandler.Retrieve<Dictionary<string, Entities.Theme>>(CACHEKEY_THEMES_INDEX_NAME);
				if (index.ContainsKey(themeName))
				{
					return index[themeName];
				}
			}

            Resources.Entities.Theme resource = mThemeRepository.GetThemeByName(themeName);
            Entities.Theme theme = null;
            if (resource != null)
            {
                theme = ConvertResourcesEntity(resource);
            }

			if (index != null)
			{
				index.Add(themeName, theme);
			}

			return theme;
		}

		#endregion

		#region Update

		public static void UpdateTheme(Entities.Theme theme)
		{
			mThemeRepository.Update(theme);
		}

		#endregion

		#region Delete

		public static void DeleteTheme(int themeId)
		{
			mThemeRepository.Remove(themeId);
		}

		public static void DeleteTheme(Entities.Theme theme)
		{
			DeleteTheme(theme.Id);
		}

		#endregion

		#endregion

		#region Internal converter methods

		internal static List<Entities.Theme> ConvertResourcesEntityList(List<Resources.Entities.Theme> list)
		{
			return list.ConvertAll<Entities.Theme>(new Converter<Resources.Entities.Theme, Entities.Theme>(ConvertResourcesEntity));
		}

		internal static Entities.Theme ConvertResourcesEntity(Resources.Entities.Theme theme)
		{
			return new Entities.Theme(theme);
		}

		#endregion

	}

}